<?php
/**
 *------------------------------------------------
 * Author: YYT[QQ:375776626]
 *------------------------------------------------
 */

//根据配置来继承对应的数据库驱动
$eval = 'class MemcacheDbDriver extends Db'.Web::config('db_driver').'{}';
eval($eval);

class DbMemcache extends MemcacheDbDriver
{
    private static $_connect = array();

    private static $_instance = null;

    public static function getInstance()
    {
        if (is_null(self::$_instance)) self::$_instance = new self();
        return self::$_instance;
    }

    private function _connect()
    {
        $servers = Web::config('db_memcache');
        $connectId = md5(serialize($servers));
        if (isset(self::$_connect[$connectId])) return self::$_connect[$connectId];
        if (!extension_loaded('memcache')) {
            throw new Exception(__METHOD__.' [没有安装memcache扩展模块]');
        }

        self::$_connect[$connectId] = new Memcache();
        if (is_array($servers)) {
            foreach ($servers as $server) {
                call_user_func_array(array(self::$_connect[$connectId], 'addServer'), $server);
                $stats = self::$_connect[$connectId]->getStats();
                if (!$stats) $connectError = true;
            }
        }
        if (isset($connectError)) throw new Exception(__METHOD__.' [连接memcache服务器失败]');
        Web::debug('Memcache: 已开启');
        return self::$_connect[$connectId];
    }

    public function query($sql, $method = '')
    {
        $method = strtolower($method);
        $table = $this->table;
        if ($method == 'fetch' || $method == 'fetchall' || $method == 'count') { //常规查询
            $data = $this->_get($sql);
            if ($data) return $data;
            $data = parent::query($sql, $method);
            $this->_add($table, $sql, $data);
            return $data;
        }
        if ($method == 'insert' || $method == 'update' || $method == 'delete') {
            $affectedRows = parent::query($sql, $method);
            if ($affectedRows > 0) {
                $this->_deletes($table);
                Web::debug('清除表<b>'.$table.'</b>在Memcache中所有缓存!');
            }
            return $affectedRows;
        }
        return parent::query($sql);
    }

    private function _addKey($table, $key)
    {
        $Memcache = $this->_connect();
        $keys = $Memcache->get($table);
        if (!$keys) $keys = array();
        if (!in_array($key, $keys)) {
            $keys[] = $key; //将新的key添加到本表的keys中
            $Memcache->set($table, $keys, MEMCACHE_COMPRESSED, 0);
            return true; //不存在返回true
        }
        return false; //存在返回false
    }

    private function _add($table, $sql, $data)
    {
        $key = md5($sql);
        if ($this->_addKey($table, $key)) {
            $Memcache = $this->_connect();
            $Memcache->set($key, $data, MEMCACHE_COMPRESSED, 0);
        }
    }

    private function _get($sql)
    {
        $key = md5($sql);
        $Memcache = $this->_connect();
        return $Memcache->get($key);
    }

    private function _deletes($table)
    {
        $Memcache = $this->_connect();
        $keys = $Memcache->get($table);
        if ($keys) {
            foreach ($keys as $key) $Memcache->delete($key, 0); //0 表示立刻删除
        }
        $Memcache->delete($table, 0);
    }
}